<?php


namespace app\controller;

use app\middleware\Auth;
use TencentCloud\Common\Credential;
use TencentCloud\Common\Exception\TencentCloudSDKException;
use TencentCloud\Sms\V20190711\Models\SendSmsRequest;
use TencentCloud\Sms\V20190711\SmsClient;
use think\Request;
use \think\response\Json;
use \Exception;

/**短信服务
 * Class ShortMsg
 * @package app\controller
 */
class ShortMsg
{
    protected $middleware = [Auth::class];

    /**发送短信
     * @param Request $request
     * @return Json
     */
    public function send(Request $request)
    {
        try {
            // 接收参数
            $input['plat'] = $request->post('plat'); // 短信平台
            if (!$input['plat']) return jsonFail('缺少参数');
            switch ($input['plat']) {
                case 'test': // 腾讯云第三方短信
                    $conf = config('msg.test');
                    if ($conf == null) return jsonFail('服务缺少配置文件，请联系管理员');
                    // 云市场分配的密钥Id
                    $secretId = $conf['secretID'];
                    // 云市场分配的密钥Key
                    $secretKey = $conf['secretKey'];
                    $source = 'market';
                    // 签名
                    $datetime = gmdate('D, d M Y H:i:s T');
                    $signStr = sprintf("x-date: %s\nx-source: %s", $datetime, $source);
                    $sign = base64_encode(hash_hmac('sha1', $signStr, $secretKey, true));
                    $auth = sprintf('hmac id="%s", algorithm="hmac-sha1", headers="x-date x-source", signature="%s"', $secretId, $sign);

                    // 请求方法
                    $method = 'POST';
                    // 请求头
                    $headers = array(
                        'X-Source' => $source,
                        'X-Date' => $datetime,
                        'Authorization' => $auth,
                    );
                    // 查询参数
                    $queryParams = array();
                    // body参数（POST方法下）
                    $bodyParams = [];
                    $bodyParams['account'] = $conf['account'];
                    $bodyParams['extno'] = $conf['extno'];
                    if (!($request->post('template'))) return jsonFail('必须包含template字段');
                    switch ($request->post('template')) {
                        case 'template1': // 模板1
                            if (!($request->post('code'))) return jsonFail('必须包含code字段');
                            if (!($request->post('expire'))) return jsonFail('必须包含expire字段');
                            if (!($request->post('mobile'))) return jsonFail('必须包含mobile字段');
                            $bodyParams['mobile'] = $request->post('mobile');
                            $content = str_replace(['{1}', '{2}'], [$request->post('code'), $request->post('expire')], $conf['template1']);
                            $bodyParams['content'] = $content;
                            break;
                        case 'template2': // 模板2
                            if (!($request->post('code'))) return jsonFail('必须包含code字段');
                            if (!($request->post('expire'))) return jsonFail('必须包含expire字段');
                            if (!($request->post('mobile'))) return jsonFail('必须包含mobile字段');
                            $bodyParams['mobile'] = $request->post('mobile');
                            $content = str_replace(['{1}', '{2}'], [$request->post('code'), $request->post('expire')], $conf['template2']);
                            $bodyParams['content'] = $content;
                            break;
                        case 'template3': // 模板3
                            if (!($request->post('mobile'))) return jsonFail('必须包含mobile字段');
                            $bodyParams['mobile'] = $request->post('mobile');
                            $bodyParams['content'] = $conf['template3'];
                            break;
                        default:
                            return jsonFail('缺少该模板，请重新核实');
                    }
                    $bodyParams['password'] = $conf['password'];
                    $bodyParams['rt'] = $conf['rt'];
                    // url参数拼接
                    $url = 'http://service-8opui4qv-1259721353.ap-shanghai.apigateway.myqcloud.com/release/smssend';
                    if (count($queryParams) > 0) {
                        $url .= '?' . http_build_query($queryParams);
                    }

                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, $url);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
                    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
                    curl_setopt($ch, CURLOPT_HTTPHEADER, array_map(function ($v, $k) {
                        return $k . ': ' . $v;
                    }, array_values($headers), array_keys($headers)));
                    if (in_array($method, array('POST', 'PUT', 'PATCH'), true)) {
                        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($bodyParams));
                    }

                    $data = curl_exec($ch);
                    if (curl_errno($ch)) {
                        curl_close($ch);
                        return jsonFail(curl_error($ch));
                    } else {
                        curl_close($ch);
                        $data = json_decode($data, true);
                        switch ($data['status']) {
                            case 0:
                                return jsonSuccess('发送成功');
                            case 1:
                                return jsonFail('消息包格式错误');
                            case 2:
                                return jsonFail('IP鉴权错误');
                            case 3:
                                return jsonFail('账号密码不正确');
                            case 4:
                                return jsonFail('版本号错误');
                            case 5:
                                return jsonFail('其它错误');
                            case 6:
                                return jsonFail('接入点错误');
                            case 7:
                                return jsonFail('账号状态异常');
                            case 15:
                                return jsonFail('余额不足');
                            default:
                                return jsonFail('未知错误');
                        }
                    }
                    break;
                case 'tx': // 腾讯云短信
                    $conf = config('msg.tx');
                    if ($conf == null) return jsonFail('服务缺少配置文件，请联系管理员');
                    $cred = new Credential($conf['secretID'], $conf['secretKey']);
                    // 实例化 SMS 的 client 对象，clientProfile 是可选的
                    $client = new SmsClient($cred, "ap-shanghai");

                    // 实例化一个 sms 发送短信请求对象，每个接口都会对应一个 request 对象。
                    $req = new SendSmsRequest();

                    /* 填充请求参数，这里 request 对象的成员变量即对应接口的入参
                     * 您可以通过官网接口文档或跳转到 request 对象的定义处查看请求参数的定义
                     * 基本类型的设置:
                       * 帮助链接：
                       * 短信控制台：https://console.cloud.tencent.com/smsv2
                       * sms helper：https://cloud.tencent.com/document/product/382/3773 */

                    /* 短信应用 ID: 在 [短信控制台] 添加应用后生成的实际 SDKAppID，例如1400006666 */
                    $req->SmsSdkAppid = $conf['SDKAppID'];
                    /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，可登录 [短信控制台] 查看签名信息 */
                    $template = $request->post('template');
                    $mobile = $request->post('mobile');
                    if (!$mobile) return jsonFail('必须包含mobile字段');
                    if (!$template) return jsonFail('必须包含template字段');
                    if (!isset($conf[$template])) return jsonFail('缺少该模板，请重新核实');
                    $req->Sign = $conf[$template]['sign'];
//                    var_dump($conf[$template]['sign']);exit;
                    /* 短信码号扩展号: 默认未开通，如需开通请联系 [sms helper] */
                    $req->ExtendCode = "0";
                    /* 下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]
                       * 例如+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号*/
                    $mobiles = explode(',', $mobile);
                    $sendMobiles = array_map(function ($v) {
                        return '+86' . $v;
                    }, $mobiles);
                    $req->PhoneNumberSet = $sendMobiles;
                    /* 国际/港澳台短信 senderid: 国内短信填空，默认未开通，如需开通请联系 [sms helper] */
                    $req->SenderId = "";
                    /* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
                    $req->SessionContext = "";
                    /* 模板 ID: 必须填写已审核通过的模板 ID。可登录 [短信控制台] 查看模板 ID */
                    $req->TemplateID = $conf[$template]['templateID'];
                    /* 模板参数: 若无模板参数，则设置为空*/
                    switch ($template) {
                        case 'template1':
                            $extends = $request->post('extends');
                            $extends = json_decode($extends,true);
                            if (!isset($extends['code'])) return jsonFail('必须包含code字段');
                            if (!isset($extends['expire'])) return jsonFail('必须包含expire字段');
                            $req->TemplateParamSet = array((string)$extends['code'],(string)$extends['expire']);
                            break;
                        case 'template2':
                            $extends = $request->post('extends');
                            $extends = json_decode($extends,true);
                            if (!isset($extends['code'])) return jsonFail('必须包含code字段');
                            if (!isset($extends['expire'])) return jsonFail('必须包含expire字段');
                            $req->TemplateParamSet = array((string)$extends['code'],(string)$extends['expire']);
                            break;
                        case 'template3':
                            $req->TemplateParamSet = [];
                            break;
                        case 'template4':
                            $extends = $request->post('extends');
                            $extends = json_decode($extends,true);
                            if (!isset($extends['code'])) return jsonFail('必须包含code字段');
                            if (!isset($extends['expire'])) return jsonFail('必须包含expire字段');
                            $req->TemplateParamSet = array((string)$extends['code'],(string)$extends['expire']);
                            break;
                    }
                    // 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
                    $resp = $client->SendSms($req);
                    // 输出 JSON 格式的字符串回包
                    $res = json_decode($resp->toJsonString(),true);
                    if ($res['SendStatusSet'][0]['Code'] == 'Ok') {
                        return jsonSuccess('发送成功');
                    } else {
                        return jsonFail($res['SendStatusSet'][0]['Message']);
                    }
                    break;
                default:
                    return jsonFail('不可用的短信平台');
            }
        } catch (TencentCloudSDKException $e) {
            return jsonFail($e->getMessage());
        } catch (Exception $e) {
            return jsonFail('服务内部错误~');
        }
    }
}